# ----------------------------------------------------------------------
# DEFINE THE STRUCTURE FOR THE ECONOMY
# ----------------------------------------------------------------------
type CE_Economy_M
    #Parameters
    β::Float64     # Discount factor
    γ::Float64     # Risk aversion
    r::Float64     # Risk free rate
    θ::Float64     # Prob of reentering markets
    α::Float64     # Learning Parameter
    σ_π::Float64   # Noise of signals
    σ_d::Float64   # Small disturbance to default value
    nb1::Int64     # Points in b grid
    nb2::Int64     # Points in b grid
    nb::Int64      # Points in b grid
  	ny::Int64      # Points in y grid
  	nz::Int64      # Points in ζ grid
  	Bval::Float64  # Value for B
    π_min::Float64 # Maximum misreport (lower bound)
    d0::Float64    # Default Cost
  	d1::Float64    # Default Cost
    ε::Float64     # Default Cost (dif)
  	η::Float64     # Output volatility
  	ρ::Float64     # Output persitence
    Πy::Matrix{Float64}  #Output Markov matrix
    ΠT::Matrix{Float64}  #Markov matrix for types
    NQ::Float64    # Average number of quarters each type is in government
    zb::Float64    # Coupon payments
    mb::Float64    # 1/Maturity
    #Grids
    z_grid_l::Float64  #Lower bound for z grid
    z_grid_u::Float64  #Upper bound for z grid
    b_grid::Array{Float64,1}       #Grid for b
  	y_grid::Array{Float64,1}       #Grid for y
    ydef_grid_I::Array{Float64,1}  #Output if default
    ydef_grid_P::Array{Float64,1}  #Output if default
  	z_grid::Array{Float64,1}       #Grid for reputation (z)
    #Matrices to store results
    UdefP::Array{Float64,1}  #Utility if in default for P-type (exogenous)
    UdefI::Array{Float64,1}  #Utility if in default for I-type (exogenous)
    WI::Array{Float64,3}     #Value function I-type (if not in default)
    WId::Array{Float64,3}    #Value function I-type (if default today)
    WIr::Array{Float64,3}    #Value function I-type (before repay)
    QI::Array{Float64,3}     #Value function I-type (if already in default - deterministic evolution of beliefs)
    WP::Array{Float64,3}
    WPd::Array{Float64,3}
    WPr::Array{Float64,3}
    QP::Array{Float64,3}
    #Debt policies & prices
    q_mat::Array{Float64,3}   # Debt Prices - Baseline Model
    bpP::Array{Float64, 3}    # Optimal debt policy - P-type
    bpI::Array{Float64, 3}    # Optimal debt policy - I-type
    #Default Policy and conjectures about default policy.
    default_I::Array{Float64,3}
    default_P::Array{Float64,3}
    default_I_bel::Array{Float64,3}
    default_P_bel::Array{Float64,3}
    #π Policy and conjectures about π
    πpol::Array{Float64,3}
    Π_exp::Array{Float64,3}
    #Additional matrices for the secondary market prices
    qA_mat::Array{Float64,3}        # Debt Prices - Secondary Market (A)
    qB_mat::Array{Float64,4}        # Debt Prices - Secondary Market (B)
    q_IIB_mat::Array{Float64,3}     # Prices for the IIB
    qA_IIB_mat::Array{Float64,3}    # Price for the IIB - Secondary Market (A)
    qB_IIB_mat::Array{Float64,4}    # Price for the IIB - Secondary Market (B)
    #Algorithm Options
    damp::Float64              # Dampening for the pricing kernel iteration
    maxiter::Int64             # Maximum number of iterations to solve the model
    model_start::Int64         # Set=1 to load previous results
    model_Chatterjee::Int64    # Set=1 to load Chatterjee model as first guess (constant types) [only relevant if model_start==0]
    save_start::Int64          # Set=1 to save results for new start
    save_final::Int64          # Set=1 to save final results
end

#-------------------------------------------------------------------------------
# Give initial values to the economy type
#-------------------------------------------------------------------------------
function ce_economy_M(;r = 0.01,
		             β       = 0.9505,
                 γ       = 2.0,
                 θ       = 0.0385,
                 α       = -0.028,
                 σ_π     = 0.011,
                 σ_d     = 0.0015,
        	       nb1 	   = 15,
                 nb2 	   = 33,
        	       ny 	   = 15,
        	       nz 	   = 15,
                 z_grid_l= 0.,
                 z_grid_u= 1.,
                 zb      = 0.03,
                 mb      = 0.05,
                 Bval    = 0.02,
                 π_min   = -0.04,
        	       d0      = -0.242,
        	       d1      = 0.325,
                 ε       = -0.0055,
                 NQ      = 32,
        	       η   	   = 0.02,
        	       ρ       = 0.93,
                 damp    = 0.97,
                 maxiter         = 1200,
                 model_start     =0,
                 model_Chatterjee=0,
                 save_start      =0,
                 save_final      =1)


#Markov Transition
pp = 1-1/(NQ)            # Transition probability
ΠT = [pp 1-pp; 1-pp pp]; # Markov Matrix fro Types

#Define Grids
#b-grid
b_grid1      = collect(linspace(  0.0,                        0.40,             nb1));
b_grid2      = collect(linspace( b_grid1[end]+b_grid1[2],     1.15,             nb2));
b_grid       = [b_grid1; b_grid2]
nb           = length(b_grid)
#z-grid
z_grid       = collect(linspace(  0.,   1.0,       nz));
#y-grid
lny_grid,Πy  = tauchen_fun(ny, ρ, η);
y_grid       = exp.(lny_grid);
#Output Cost: I and P types
ydef_grid_I = y_grid-max.((d0+ε)*y_grid+d1*y_grid.^2, 1e-14);
ydef_grid_P = y_grid-max.((d0-ε)*y_grid+d1*y_grid.^2, 1e-14);

#Output & Utility if in default (exogenous)
UdefP = zeros(ny);
UdefI = zeros(ny);
u_fun_def(c,γ) = (c.^(1.0-γ))/(1.0-γ);
for (i_y, y_v) in enumerate(y_grid);
  ydf_I = y_v-max((d0+ε)*y_v+d1*y_v.^2, 1e-14);
  ydf_P = y_v-max((d0-ε)*y_v+d1*y_v.^2, 1e-14);
  UdefP[i_y] = u_fun_def(ydf_P,γ);
  UdefI[i_y] = u_fun_def(ydf_I,γ);
end

#Matrices to store results: Prices, Policies, & Conjectures
  q_mat         = ones(nb, ny, nz) / (1.0+r);
  bpP 	        = zeros(nb, ny, nz);
  bpI 	        = zeros(nb, ny, nz);
  πpol 	        = zeros(nb, ny, nz);
  default_I     = zeros(nb, ny, nz);
  default_P     = zeros(nb, ny, nz);
  #Conjectures
  Π_exp         = ones(nb, ny, nz)*(-.02);
  default_I_bel = zeros(nb, ny, nz);
  default_P_bel = zeros(nb, ny, nz);

#Matrices to store results: Value Functions
  WP 	    = -10*ones(nb, ny, nz);
  WPd     = -10*ones(nb, ny, nz);
  WPr     = -10*ones(nb, ny, nz);
  QP      = -10*ones(nb, ny, nz);
  WI 	    = -10*ones(nb, ny, nz);
  WId     = -10*ones(nb, ny, nz);
  WIr     = -10*ones(nb, ny, nz);
  QI      = -10*ones(nb, ny, nz);

 #Additional matrices for secondary markets
 qA_mat      = ones(nb, ny, nz) / (1.0+r);
 qB_mat      = ones(nb, ny, nz,2) / (1.0+r);
 q_IIB_mat   = similar(q_mat);
 qA_IIB_mat  = similar(q_mat);
 qB_IIB_mat  = similar(qB_mat);

return CE_Economy_M(  β, γ, r, θ, α, σ_π, σ_d,
                      nb1,nb2, nb, ny, nz,
                      Bval, π_min, d0, d1, ε, η, ρ, Πy, ΠT, NQ, zb,mb,
                      z_grid_l, z_grid_u,
                      b_grid, y_grid, ydef_grid_I, ydef_grid_P, z_grid,
                      UdefP,UdefI,
                      WI, WId, WIr, QI, WP, WPd,WPr, QP,
                      q_mat,  bpP, bpI,
                      default_I, default_P, default_I_bel, default_P_bel,
                      πpol, Π_exp,
                      qA_mat, qB_mat, q_IIB_mat, qA_IIB_mat, qB_IIB_mat,
                      damp, maxiter, model_start, model_Chatterjee, save_start, save_final);
end
#-------------------------------------------------------------------------------
